import os
from io import BytesIO

import requests
from concurrent.futures import ThreadPoolExecutor
from bs4 import BeautifulSoup
from PIL import Image
from tqdm import tqdm
import concurrent.futures
import utils


def getLimit(start_url, end_url):
    start_row = int(start_url.split("/")[-2])
    start_col = int(start_url.split("/")[-1])
    end_row = int(end_url.split("/")[-2])
    end_col = int(end_url.split("/")[-1])
    level = int(end_url.split("/")[-3])
    return [start_row, start_col, end_row, end_col, level]


def genercl(strat_url, end_url):
    start_row, start_col, end_row, end_col, level = getLimit(strat_url, end_url)
    urls = []
    for row in range(start_row, end_row + 1):
        for col in range(start_col, end_col + 1):
            urls.append([level, row, col])
    return urls


def parseServiceInfo(serviceUrl):
    html_doc = requests.get(serviceUrl).text
    soup = BeautifulSoup(html_doc, 'html.parser')
    # /arcgis/rest/services/bejing/MapServer/tile/0/40/40
    start_urls = soup.find_all('a', text="Start Tile")
    end_urls = soup.find_all('a', text="End Tile")
    return start_urls, end_urls


def getrclInfo(serviceUrl, level):
    start_urls, end_urls = parseServiceInfo(serviceUrl)
    level_row_cols = []
    if level != -1:
        level_row_cols = genercl(start_urls[level]["href"], end_urls[level]["href"])
    else:
        for l in range(len(start_urls)):
            level_row_cols.extend(genercl(start_urls[l]["href"], end_urls[l]["href"]))
    return level_row_cols


def getSavaPath(saveDir, row, col, level, _isAGSTileMode=True):
    if _isAGSTileMode:
        row = utils.code_10_to_ags16(row)
        col = utils.code_10_to_ags16(col)
    if _isAGSTileMode and level < 10:
        level = "0" + str(level)
    else:
        level = str(level)
    savePath = saveDir + "/" + "L{0}/R{1}/C{2}.png".format(level, row, col)
    return savePath


def downLoad(serviceUrls, saveDir, row, col, level, _isAGSTileMode=True):
    request_url = serviceUrls + "/tile/{0}/{1}/{2}".format(level, row, col)
    response = requests.get(request_url)
    img = Image.open(BytesIO(response.content))
    save_path = getSavaPath(saveDir, row, col, level, True)
    if not os.path.exists(save_path):
        if not os.path.exists(os.path.dirname(save_path)):
            os.makedirs(os.path.dirname(save_path))
        img.save(save_path)


def get_tile_to_file(serviceUrls, saveDir, level, _isAGSTileMode=True):
    num_threads = 5
    with ThreadPoolExecutor(max_workers=num_threads) as executor:
        futures = [executor.submit(downLoad, serviceUrls, saveDir, row, col, l, _isAGSTileMode) for l, row, col in
                   getrclInfo(serviceUrls, level)]
        for future in tqdm(concurrent.futures.as_completed(futures), total=len(futures)):
            pass
    # for l, row, col in getrclInfo(serviceUrls, level):
    #     executor.submit(downLoad, serviceUrls, saveDir, row, col, l, _isAGSTileMode)


if __name__ == '__main__':
    get_tile_to_file(r"http://localhost:6080/arcgis/rest/services/bejing/MapServer",
                     r"D:\PROJECT\PYTHON\arcgisBundleConvert\tile", -1)
